package com.csinc.generate.onekey;

import com.csinc.generate.core.CodeGenModel;
import com.csinc.generate.core.CodeGenUtil;
import com.csinc.generate.core.constant.GenCoreConstant;
import com.csinc.generate.core.utils.io.FileUtils;
import com.csinc.generate.core.utils.io.PropertiesUtils;
import com.csinc.generate.core.utils.io.ResourceUtils;
import com.csinc.generate.core.base.model.GenerationEntity;
import com.csinc.generate.core.base.model.TemplateModel;
import com.csinc.generate.core.util.NameUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Create By 郭金宝 on 2018/7/25.<br>
 */
@Slf4j
@Data
public class MakeCodeByTable {

    private volatile static MakeCodeByTable generatCodeByTable;

    private CodeGenModel codeGenModel = new CodeGenModel();
    private List<String> outFileList = new ArrayList<String>();
    private String localPath = "D:\\source\\csinc.generate\\generate-template";


    public static MakeCodeByTable GenMake(String localPath) {
        if (generatCodeByTable == null) {
            synchronized (MakeCodeByTable.class) {
                if (generatCodeByTable == null) {
                    generatCodeByTable = new MakeCodeByTable(localPath);
                }
            }
        }
        return generatCodeByTable;
    }


    /**
     * 根据要生成的表，创建文件
     */

    private MakeCodeByTable(String localPath) {
        setLocalPath(localPath);
        make();
    }


    private void make() {
        PropertiesUtils propertiesUtils = new PropertiesUtils("CodeMakeProperties.properties");
        codeGenModel.setDbType(propertiesUtils.getProperty("codeGenModel.dbType"));
        codeGenModel.setDbName(propertiesUtils.getProperty("codeGenModel.dbName"));
        codeGenModel.setParseType(propertiesUtils.getProperty("codeGenModel.parseType"));
        codeGenModel.setUrl(propertiesUtils.getProperty("codeGenModel.url"));
        codeGenModel.setUsername(propertiesUtils.getProperty("codeGenModel.username"));
        codeGenModel.setPasswd(propertiesUtils.getProperty("codeGenModel.passwd"));
        codeGenModel.setTableName(propertiesUtils.getProperty("codeGenModel.tableName"));
        //以下是创建文件包信息
        codeGenModel.getGenerationEntity().setCodePackage("com.csinc.generate");
        codeGenModel.getGenerationEntity().setEntityName(NameUtil.getEntityHumpName(codeGenModel.getTableName()));
        codeGenModel.getGenerationEntity().setAuthor("kingboy");
        codeGenModel.getGenerationEntity().setCopyright("/** copyright By @ kingboy **/");
        codeGenModel.getGenerationEntity().setTableName(codeGenModel.getTableName());
        codeGenModel.getGenerationEntity().setName(propertiesUtils.getProperty("codeGenModel.generationEntity.name"));
        codeGenModel.getGenerationEntity().setHtmlPackage("biz");
        codeGenModel.getGenerationEntity().setJsPackage("biz");
        initTemplateModel("/beetl/web/");
        outFileList.addAll(CodeGenUtil.makeGen(codeGenModel));
        //将生成的模板输出到本地文件夹
        writeThisFileList(localPath, "UTF-8", outFileList, codeGenModel.getListTemplateModel(), codeGenModel.getGenerationEntity());
    }


    /**
     * 本地输出代码
     */
    private void writeThisFileList(String localPath, String encoded, List<String> fileList, List<TemplateModel> templateList, GenerationEntity ge) {
        for (int i = 0; i < fileList.size(); i++) {
            // 文件路径包括 本地项目路径 + 项目相对路径 + 包路径 + 类的自我路径
            String filePath = localPath + File.separator +
                    (StringUtils.isNotEmpty(templateList.get(i).getLocalPath()) ?
                            templateList.get(i).getLocalPath().replaceAll("\\.", "\\/") + File.separator : "") +
                    getPackagePath(templateList.get(i), ge);
            log.info("生成的文件路径是：" + filePath);
            File path = new File(filePath + File.separator);
            if (!path.exists()) {
                path.mkdirs();
            }
            try {
                File file = new File(filePath + File.separator + getFileName(templateList.get(i), ge));
                FileUtils.writeStringToFile(file, fileList.get(i), encoded);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }


    public String getPackagePath(TemplateModel templateModel, GenerationEntity ge) {
        if (templateModel.getFileName().endsWith("js")) {
            return ge.getJsPackage().replaceAll("\\.", "\\/")
                    + (StringUtils.isNotEmpty(templateModel.getTemplatePath()) ? "/"
                    + templateModel.getTemplatePath().replaceAll("\\.", "\\/") : "");
        } else if (templateModel.getFileName().endsWith("html")) {
            return ge.getHtmlPackage().replaceAll("\\.", "\\/")
                    + (StringUtils.isNotEmpty(templateModel.getTemplatePath()) ? "/"
                    + templateModel.getTemplatePath().replaceAll("\\.", "\\/") : "");
        } else if (templateModel.getFileName().endsWith("xml")) {
            return ge.getXmlPackage().replaceAll("\\.", "\\/")
                    + (StringUtils.isNotEmpty(templateModel.getTemplatePath()) ? "/"
                    + templateModel.getTemplatePath().replaceAll("\\.", "\\/") : "");
        } else {
            return ge.getCodePackage().replaceAll("\\.", "\\/")
                    + (StringUtils.isNotEmpty(templateModel.getTemplatePath()) ? "/"
                    + templateModel.getTemplatePath().replaceAll("\\.", "\\/") : "");
        }
    }

    private String getFileName(TemplateModel templateModel, GenerationEntity ge) {
        if (templateModel.getFileName().endsWith("js")) {
            return String.format(templateModel.getFileName(), ge.getEntityName().toLowerCase());
        } else if (templateModel.getFileName().endsWith("html")) {
            return String.format(templateModel.getFileName(), ge.getEntityName().toLowerCase());
        } else if (templateModel.getFileName().endsWith("xml")) {
            return String.format(templateModel.getFileName(), ge.getEntityName());
        } else {
            return String.format(templateModel.getFileName(), ge.getEntityName());
        }
    }

    /**
     * 增加要创建的模板信息
     */
    private void initTemplateModel(String path) {

        TemplateModel controllerTemplateModel = new TemplateModel();
        controllerTemplateModel.setFileName("%sController.java");
        controllerTemplateModel.setTemplateDesc("自动创建的Controller");
        controllerTemplateModel.setTemplatePath("controller");
        controllerTemplateModel.setLocalPath("src\\main\\java");
        controllerTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        controllerTemplateModel.setVersion(1);
        controllerTemplateModel.setTemplateName("Controller模板");
        controllerTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Controller.java"));
        codeGenModel.getListTemplateModel().add(controllerTemplateModel);

        TemplateModel serviceTemplateModel = new TemplateModel();
        serviceTemplateModel.setFileName("I%sService.java");
        serviceTemplateModel.setTemplateDesc("自动创建的Service");
        serviceTemplateModel.setTemplatePath("service");
        serviceTemplateModel.setLocalPath("src\\main\\java");
        serviceTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        serviceTemplateModel.setVersion(1);
        serviceTemplateModel.setTemplateName("IService模板");
        serviceTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "IService.java"));
        codeGenModel.getListTemplateModel().add(serviceTemplateModel);

        TemplateModel serviceImplTemplateModel = new TemplateModel();
        serviceImplTemplateModel.setFileName("%sServiceImpl.java");
        serviceImplTemplateModel.setTemplateDesc("自动创建的ServiceImpl");
        serviceImplTemplateModel.setTemplatePath("service.impl");
        serviceImplTemplateModel.setLocalPath("src\\main\\java");
        serviceImplTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        serviceImplTemplateModel.setVersion(1);
        serviceImplTemplateModel.setTemplateName("ServiceImpl模板");
        serviceImplTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "ServiceImpl.java"));
        codeGenModel.getListTemplateModel().add(serviceImplTemplateModel);


        TemplateModel daoTemplateModel = new TemplateModel();
        daoTemplateModel.setFileName("%sDao.java");
        daoTemplateModel.setTemplateDesc("自动创建的Dao");
        daoTemplateModel.setTemplatePath("dao");
        daoTemplateModel.setLocalPath("src\\main\\java");
        daoTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        daoTemplateModel.setVersion(1);
        daoTemplateModel.setTemplateName("Dao模板");
        daoTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Dao.java"));
        codeGenModel.getListTemplateModel().add(daoTemplateModel);


        TemplateModel modelTemplateModel = new TemplateModel();
        modelTemplateModel.setFileName("%sModel.java");
        modelTemplateModel.setTemplateDesc("自动创建的Model");
        modelTemplateModel.setTemplatePath("model");
        modelTemplateModel.setLocalPath("src\\main\\java");
        modelTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        modelTemplateModel.setVersion(1);
        modelTemplateModel.setTemplateName("Model模板");
        modelTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Model.java"));
        codeGenModel.getListTemplateModel().add(modelTemplateModel);

        TemplateModel mappinglTemplateModel = new TemplateModel();
        mappinglTemplateModel.setFileName("%sMapping.xml");
        mappinglTemplateModel.setTemplateDesc("自动创建的Mapping");
        mappinglTemplateModel.setTemplatePath("dao.mapping");
        mappinglTemplateModel.setLocalPath("src\\main\\java");
        mappinglTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        mappinglTemplateModel.setVersion(1);
        mappinglTemplateModel.setTemplateName("Mapping模板");
        mappinglTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Mapping.xml"));
        codeGenModel.getListTemplateModel().add(mappinglTemplateModel);


        TemplateModel pagelTemplateModel = new TemplateModel();
        pagelTemplateModel.setFileName("%s.html");
        pagelTemplateModel.setTemplateDesc("表单基础界面");
        pagelTemplateModel.setLocalPath("src\\main\\webapp\\WEB-INF\\view");
        pagelTemplateModel.setTemplatePath(codeGenModel.getGenerationEntity().getEntityName().toLowerCase());
        pagelTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        pagelTemplateModel.setVersion(1);
        pagelTemplateModel.setTemplateName("Html模板");
        pagelTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Page.html"));
        codeGenModel.getListTemplateModel().add(pagelTemplateModel);

        TemplateModel pageAddlTemplateModel = new TemplateModel();
        pageAddlTemplateModel.setFileName("%s_add.html");
        pageAddlTemplateModel.setTemplateDesc("表单新增界面");
        pageAddlTemplateModel.setLocalPath("src\\main\\webapp\\WEB-INF\\view");
        pageAddlTemplateModel.setTemplatePath(codeGenModel.getGenerationEntity().getEntityName().toLowerCase());
        pageAddlTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        pageAddlTemplateModel.setVersion(1);
        pageAddlTemplateModel.setTemplateName("Html模板");
        pageAddlTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "PageAdd.html"));
        codeGenModel.getListTemplateModel().add(pageAddlTemplateModel);


        TemplateModel pageEditlTemplateModel = new TemplateModel();
        pageEditlTemplateModel.setFileName("%s_edit.html");
        pageEditlTemplateModel.setTemplateDesc("表单编辑界面");
        pageEditlTemplateModel.setLocalPath("src\\main\\webapp\\WEB-INF\\view");
        pageEditlTemplateModel.setTemplatePath(codeGenModel.getGenerationEntity().getEntityName().toLowerCase());
        pageEditlTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        pageEditlTemplateModel.setVersion(1);
        pageEditlTemplateModel.setTemplateName("Html模板");
        pageEditlTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "PageEdit.html"));
        codeGenModel.getListTemplateModel().add(pageEditlTemplateModel);

        TemplateModel jslTemplateModel = new TemplateModel();
        jslTemplateModel.setFileName("%s.js");
        jslTemplateModel.setTemplateDesc("基础的js");
        jslTemplateModel.setLocalPath("src\\main\\webapp\\static\\csinc");
        jslTemplateModel.setTemplatePath(codeGenModel.getGenerationEntity().getEntityName().toLowerCase());
        jslTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        jslTemplateModel.setVersion(1);
        jslTemplateModel.setTemplateName("js模板");
        jslTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "Page.js"));
        codeGenModel.getListTemplateModel().add(jslTemplateModel);

        TemplateModel jsInfolTemplateModel = new TemplateModel();
        jsInfolTemplateModel.setFileName("%s_info.js");
        jsInfolTemplateModel.setTemplateDesc("pageInfoJs");
        jsInfolTemplateModel.setLocalPath("src\\main\\webapp\\static\\csinc");
        jsInfolTemplateModel.setTemplatePath(codeGenModel.getGenerationEntity().getEntityName().toLowerCase());
        jsInfolTemplateModel.setTemplateType(GenCoreConstant.BEETL);
        jsInfolTemplateModel.setVersion(1);
        jsInfolTemplateModel.setTemplateName("js模板");
        jsInfolTemplateModel.getFileModel().setFile(ResourceUtils.getResourceFileContent(path + "PageInfo.js"));
        codeGenModel.getListTemplateModel().add(jsInfolTemplateModel);


    }

}
